package com.burt.springcloudconfigclientdemo;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.bootstrap.config.PropertySourceLocator;
import org.springframework.cloud.context.refresh.ContextRefresher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import com.burt.springcloudconfigclientdemo.health.MyHealthIndicator;

@SpringBootApplication
@EnableScheduling
public class SpringCloudConfigClientDemoApplication {

    private final ContextRefresher contextRefresher;

    private final Environment      environment;

    @Autowired
    public SpringCloudConfigClientDemoApplication(ContextRefresher contextRefresher, Environment environment) {
        this.contextRefresher = contextRefresher;
        this.environment = environment;
    }

    public static void main(String[] args) {
        //        SpringApplication application = new SpringApplication(SpringCloudConfigClientDemoApplication.class);
        //        application.setWebApplicationType(WebApplicationType.SERVLET);
        //        application.run(args);
        SpringApplication.run(SpringCloudConfigClientDemoApplication.class, args);
    }

    /**
     * 定时获取配置文件
     */
    @Scheduled(fixedRate = 5 * 1000, initialDelay = 3 * 1000)
    public void autoRefresh() {
        System.out.println("定时获取配置文件");
        Set<String> updateConfigs = contextRefresher.refresh();
        updateConfigs.stream().forEach(c -> System.err.printf("[Thread :%s] 当前配置已更新，具体 Key：%s , Value : %s \n",
                Thread.currentThread().getName(), c, environment.getProperty(c)));
    }

    /**
     * 自定义健康指示器
     *
     * @return
     */
    @Bean
    public MyHealthIndicator myHealthIndicator() {
        return new MyHealthIndicator();
    }

    /**
     * BootstrapApplicationListener Spring Cloud "/META-INF/spring.factories": #
     * Application Listeners org.springframework.context.ApplicationListener=\
     * org.springframework.cloud.bootstrap.BootstrapApplicationListener,\
     * org.springframework.cloud.bootstrap.LoggingSystemShutdownListener,\
     * org.springframework.cloud.context.restart.RestartListener
     */
    /**
     * 加载的优先级 高于 ConfigFileApplicationListener，所以 application.properties
     * 文件即使定义也配置不到！ 原因在于： BootstrapApplicationListener 第6优先
     * ConfigFileApplicationListener 第11优先。所以使用如下方式修改配置文件参数
     */
    @Configuration
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public static class MyPropertySourceLocator implements PropertySourceLocator {

        @Override
        public PropertySource<?> locate(Environment environment) {
            Map<String, Object> source = new HashMap<>();
            source.put("server.port", "8080");
            MapPropertySource propertySource = new MapPropertySource("my-property-source", source);
            return propertySource;
        }
    }
}
